Skip to main content

Priority Rules

When a request comes in, NGINX may have multiple location blocks that could match. To avoid ambiguity, NGINX follows a strict priority algorithm to select one—and only one—location.

The 4 Location Types (in Priority Context)

TypeSyntaxPriority
Exact matchlocation = /pathHighest
Prefix match (^~)location ^~ /path/High
Regex matchlocation ~, ~*Medium
Normal prefix matchlocation /path/Low (longest wins)

The Actual Matching Algorithm (Step by Step)

NGINX processes locations in this exact order:

1. Exact Match (=)

location = /login {
return 403;
}
  • If the request URI is exactly /login
  • NGINX immediately stops searching
  • No other locations are checked

Nothing can override an exact match

2. Prefix Match with ^~

location ^~ /static/ {
root /var/www/static;
}
  • NGINX checks prefix locations marked with ^~
  • If matched:
    • Regex checks are skipped entirely
    • This location is selected

Used to protect important prefixes from regex overrides

3. Regex Matches (~, ~*)

location ~ \.php$ {
fastcgi_pass php;
}
  • Regex locations are tested in the order they appear
  • First matching regex wins
  • Order matters!

Regex can override normal prefix matches

4. Normal Prefix Matches

location /api/ {
proxy_pass http://api;
}

location / {
try_files $uri $uri/ =404;
}
  • Among normal prefixes:
    • Longest matching prefix wins
  • /api/ beats /

Visual Priority Order (Memory Trick)

=   (Exact)
^~ (Strong prefix)
~ (Regex – first match wins)
/ (Longest normal prefix)

Full Example with Multiple Matches

server {

location = /admin {
return 403;
}

location ^~ /static/ {
root /var/www/static;
}

location ~ \.php$ {
fastcgi_pass php;
}

location /static/images/ {
root /var/www/images;
}

location / {
try_files $uri $uri/ =404;
}
}

Request-by-Request Breakdown

  1. Request 1: /admin

    • Exact match exists
    • location = /admin is selected
  2. Request 2: /static/logo.png

    • Matches ^~ /static/
    • Regex is skipped
    • /static/ location used
  3. Request 3: /static/images/a.php

    • ^~ /static/ matches
    • Regex is skipped
    • /static/ (not .php)
  4. Request 4: /index.php

    • No exact match
    • No ^~ prefix
    • Regex \.php$ matches
    • PHP location selected
  5. Request 5: /about/team

    • No exact
    • No ^~
    • No regex
    • Prefix / used
    • default handler

Why ^~ Exists (Very Important)

Without ^~:

location /images/ {
root /var/www/images;
}

location ~ \.jpg$ {
root /var/www/jpg;
}
  • Request: /images/photo.jpg
  • Regex wins → wrong directory

Fix

location ^~ /images/ {
root /var/www/images;
}